﻿using Ionic.Zip;
using Microsoft.Web.Administration;
using PLM.ConfigurationCenter.Core.Expansion;
using PLM.ConfigurationCenter.Model;
using PLM.ConfigurationCenter.Service;
using PLM.ConfigurationCenter.SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.ServiceProcess;
using System.Text;
using System.Threading;

namespace PLM.ConfigurationCenter.Handler {
    /// <summary>
    /// 
    /// </summary>
    public class ServerHandler {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static string GetLocalIP() {
            string localIP = "127.0.0.1";
            using (Socket socket = new(AddressFamily.InterNetwork, SocketType.Dgram, 0)) {
                socket.Connect("8.8.8.8", 65530);
                IPEndPoint? endPoint = socket.LocalEndPoint as IPEndPoint;
                localIP = endPoint!.Address.ToString();
            }
            return localIP;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static bool CheckSitePort(int port) {
            bool inUse = false;
            IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
            IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
            foreach (IPEndPoint endPoint in ipEndPoints) {
                if (endPoint.Port == port) {
                    inUse = true;
                    break;
                }
            }
            return inUse;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static List<ServerModel> GetDefaultServerList() {
            var arr = new List<ServerModel> {
                    new ServerModel { Tag = "核心服务", Id = "API", SiteLabel = "后端服务" },
                    new ServerModel { Tag = "核心服务", Id = "WEB", SiteLabel = "前端服务" },
                    new ServerModel { Tag = "核心服务", Id = "COMMONITEM", SiteLabel = "缓存服务" },
                    new ServerModel { Tag = "基础服务", Id = "REDIS", SiteLabel = "Redis服务" },
                    new ServerModel { Tag = "基础服务", Id = "FILESTORE", SiteLabel = "文件服务" },
                    new ServerModel { Tag = "扩展服务", Id = "ADAPTER", SiteLabel = "ERP对接服务" },
                    new ServerModel { Tag = "扩展服务", Id = "JOBCENTER", SiteLabel = "定时任务中心" }
                };
            return arr;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static void FillDefaultServer(ServerModel model) {
            switch (model.Id) {
                case "REDIS":
                    model.SiteName = "REDIS";
                    model.SitePort = 6379;
                    model.SiteLabel = "Redis服务";
                    break;
                case "WEB":
                    model.SiteName = "PLM_WEB_VUE";
                    model.SitePort = 3039;
                    model.SiteLabel = "前端服务";
                    break;
                case "API":
                    model.SiteName = "PLM_WEB";
                    model.SitePort = 3031;
                    model.SiteLabel = "后端服务";
                    break;
                case "ADAPTER":
                    model.SiteName = "ADAPTER";
                    model.SitePort = 3132;
                    model.SiteLabel = "ERP对接服务";
                    break;
                case "COMMONITEM":
                    model.SiteName = "COMMONITEM";
                    model.SitePort = 3301;
                    model.SiteLabel = "缓存服务";
                    break;
                case "FILESTORE":
                    model.SiteName = "FILESTORE";
                    model.SitePort = 8111;
                    model.SiteLabel = "文件服务";
                    break;
                case "INSTALLATION":
                    model.SiteName = "INSTALLATION";
                    model.SitePort = 3130;
                    model.SiteLabel = "同步中心";
                    break;
                case "JOBCENTER":
                    model.SiteName = "JOBCENTER";
                    model.SitePort = 3031;
                    model.SiteLabel = "定时任务中心";
                    break;
                default:
                    break;
            }
            model.IpAddress = GetLocalIP();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static string GetSitePath(string id, string siteName) {
            var setting = DbManager.DbContext.Queryable<SystemSettingModel>().Where(p => p.Name == "RootDic").First();
            string rootPath = setting?.Value?.ToString() ?? string.Empty;
            string path = id switch {
                "REDIS" => Path.Combine(rootPath, "ADDIN\\" + siteName),
                "WEB" or "API" => Path.Combine(rootPath, siteName),
                _ => Path.Combine(rootPath, "PLM_WEB_PARTICAL\\" + siteName),
            };
            return path;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static string GetSiteStatusInfo(ServerModel model) {
            string path = model.Status switch {
                1 => "未初始化",
                2 => "未安装",
                3 => "未运行",
                4 => "已运行",
                _ => "未配置服务信息,双击左侧服务进行配置",
            };
            return path;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static ServerModel GetServerModel(string id) {
            var model = DbManager.DbContext.Queryable<ServerModel>().Where(p => p.Id == id).First();
            return model;
        }

        #region 初始化前端配置文件
        /// <summary>
        /// 初始化前端配置文件
        /// </summary>
        public static bool InitWebConfig(out string error) {
            error = "";
            var model = GetServerModel("WEB");
            if (model == null) {
                return false;
            }
            var apimodel = GetServerModel("API");
            var sitePath = GetSitePath(model.Id, model.SiteName);
            string configPath = Path.Combine(sitePath, $"config.js");
            var str = new StringBuilder();
            str.AppendLine("const Glod = {");
            str.AppendLine("  MarkFormat: '', // 请求格式日期format");
            str.AppendLine("  BaseUrl: '{protocol}//{hostname}{port}', // 路径 默认端3031");
            str.AppendLine($"  BaseUrlLocal: 'http://localhost:{apimodel?.SitePort}', // 接口路径 默认端3031");
            str.AppendLine("  FilePreviewUrl: '{protocol}//{hostname}{port}', //文件预览url  默认端口为3319");
            str.AppendLine("  AutoVueUrl: '{protocol}//{hostname}{port}' //AutoVue预览url  默认端口为5098");
            str.AppendLine("}");

            str.AppendLine("/*");
            str.AppendLine(" * 如内外网一致 则 跳过此步配置");
            str.AppendLine(" * 如果内外网端口不一致 如");
            str.AppendLine(" * 内网 3039 3031 3319");
            str.AppendLine(" * 外网对应 93039  93031  93319  外网ip为  111.222.333.444");
            str.AppendLine(" * 'http://111.222.333.444:93039#BaseUrl': '{protocol}//{hostname}:93031',");
            str.AppendLine(" * 'http://111.222.333.444:93039#FilePreviewUrl': '{protocol}//{hostname}:93319'");
            str.AppendLine(" */");
            str.AppendLine("const GloMap = {");
            str.AppendLine("  'http://111.222.333.444:93039#BaseUrl': '{protocol}//{hostname}:93031',");
            str.AppendLine("  'http://111.222.333.444:93039#FilePreviewUrl': '{protocol}//{hostname}:93319'");
            str.AppendLine("}");
            str.AppendLine("");
            str.AppendLine("");
            str.AppendLine("");

            str.AppendLine("function replaceUrl(url, key) {");
            str.AppendLine("  var protocol = location.protocol");
            str.AppendLine("  var hostname = location.hostname");
            str.AppendLine("  var port = location.port === '' ? '' : ':' + location.port");
            str.AppendLine("  var path = location.pathname");
            str.AppendLine("  key = `${protocol}//${hostname}${port}#${key}`");
            str.AppendLine("  if (!!GloMap[key]) {");
            str.AppendLine("\turl = GloMap[key]");
            str.AppendLine("  }");
            str.AppendLine("  url = url.replace('{protocol}', protocol).replace('{hostname}', hostname).replace('{port}', port).replace('{path}', path)");
            str.AppendLine("  return url");
            str.AppendLine("}");

            str.AppendLine("for (var prop in Glod) {");
            str.AppendLine("  Glod[prop] = replaceUrl(Glod[prop], prop)");
            str.AppendLine("  console.log('Glod.' + prop + ' = ' + Glod[prop])");
            str.AppendLine("}");
            str.AppendLine("console.log(Glod)");
            str.AppendLine("window.Glod = Glod");


            CommonServerHelper.WriteFile(configPath, str.ToString());
            return true;
        }
        #endregion
        #region 初始化缓存服务配置文件
        /// <summary>
        /// 初始化缓存服务配置文件
        /// </summary>
        public static bool InitCommonitemConfig(string sitePath, out string error) {
            error = "";
            var dbModel = DbManager.DbContext.Queryable<DatabaseInfoModel>().First(p => p.Id == "AuxiliaryDb");
            if (dbModel == null) {
                error = "未配置辅助数据库！";
                return false;
            }
            string filePath = Path.Combine(sitePath, $"appsettings.json");
            var webModel = GetServerModel("API");
            var model = GetServerModel("COMMONITEM");

            var templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data\\CommonItem\\appsettings.json");
            var allLines = File.ReadAllLines(templateFile);
            var strList = new List<string>();
            foreach (var line in allLines) {
                var item = line.Replace("$C.DbConn", CommonServerHelper.GetDBConn(dbModel))
                               .Replace("$C.DbType", "NPGSQL")
                               .Replace("$C.ApiPort", webModel?.SitePort.ToString())
                               .Replace("$C.Port", model.SitePort.ToString());
                strList.Add(item);
            }
            CommonServerHelper.WriteFile(filePath, strList);
            return true;
        }
        #endregion
        #region 初始化文件服务器配置文件
        /// <summary>
        /// 初始化文件服务器配置文件
        /// </summary>
        public static bool InitFileStoreConfig(string sitePath, out string error) {
            error = "";
            var dbModel = DbManager.DbContext.Queryable<DatabaseInfoModel>().First(p => p.Id == "BaseDb");
            if (dbModel == null) {
                error = "未配置主数据库！";
                return false;
            }
            string filePath = Path.Combine(sitePath, $"appsettings.json");
            var dbType = dbModel.DBType == 1 ? "SQLSERVER" : "ORACLE";
            var model = GetServerModel("API");
            var strList = new List<string> {
                "{",
                "\t\"Logging\": {",
                "\t\t\"LogLevel\": {",
                "\t\t\t\"Default\": \"Error\",",
                "\t\t\t\"Microsoft\": \"Error\",",
                "\t\t\t\"Microsoft.Hosting.Lifetime\": \"Error\"",
                "\t\t}",
                "\t},",
                "\t\"AllowedHosts\": \"*\",",
                "\t\"ConnectionStrings\": {",
                $"\t\t\"DbConn\": \"{CommonServerHelper.GetDBConn(dbModel)}\",",
                $"\t\t\"DbType\": \"{dbType}\"",
                "\t},",
                $"\t\"Urls\": \"http://*:{model.SitePort}\",",
                "\t\"Elasticsearch\": {",
                "\t\t\"Uri\": \"http://192.168.2.102:3092/\",",
                "\t\t\"DefaultIndex\": \"stdtrainnings\",",
                "\t\t\"UserName\": \"elastic\",",
                "\t\t\"PassWord\": \"123456\",",
                "\t\t\"AllowFileTypes\": \"[\\\"BASH\\\",\\\"SH\\\",\\\"TXT\\\",\\\"DOC\\\",\\\"DOCX\\\",\\\"JSON\\\",\\\"LOG\\\",\\\"PPTX\\\",\\\"PPT\\\",\\\"XLS\\\",\\\"XLSX\\\",\\\"PDF\\\",\\\"XML\\\",\\\"VUE\\\",\\\"HTML\\\"]\"",
                "\t},",
                "\t\"Hosts\": {",
                "\t\t\"DBServer\": [",
                "\t\t],",
                "\t\t\"FileServer\": [",
                "\t\t\t{",
                "\t\t\t\t\"oid\": \"ef3bec9b-a926-4322-8634-227ad6a5d0d7\",",
                $"\t\t\t\t\"hostName\": \"{Environment.MachineName}\",",
                $"\t\t\t\t\"ipAddress\": \"{GetLocalIP()}\",",
                "\t\t\t\t\"port\": \"8011\",",
                "\t\t\t\t\"monitorPort\": \"8012\",",
                "\t\t\t\t\"bufferPath\": \"c:\\\\fileTempa\",",
                "\t\t\t\t\"bufferSize\": \"524288\",",
                "\t\t\t\t\"maxPoolNum\": \"100\",",
                "\t\t\t\t\"minPoolNum\": \"10\",",
                "\t\t\t\t\"threadTimeOut\": \"0\",",
                "\t\t\t\t\"gcPollingTime\": \"300\",",
                "\t\t\t\t\"allowDebugLog\": \"true\",",
                "\t\t\t\t\"fileBuffSize\": \"1000\",",
                "\t\t\t\t\"bufferClearSize\": \"200\"",
                "\t\t\t}",
                "\t\t],",
                "\t\t\"CacheServer\": [],",
                "\t\t\"FileSynServer\": [],",
                "\t\t\"AccessOrder\": [],",
                "\t\t\"AccessRule\": []",
                "\t}",
                "}",
            };
            CommonServerHelper.WriteFile(filePath, strList);
            return true;
        }
        #endregion

        #region 初始化Redis
        /// <summary>
        /// 初始化Redis
        /// </summary>
        public static bool InitRedis(string rootPath, out string error) {
            error = "";
            var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data\\redis.zip");
            var configPath = Path.Combine(rootPath, "redis");
            if (Directory.Exists(configPath)) {
                error = "未配置辅助数据库！";
                return false;
            }
            using ZipFile zip = new(filePath);
            zip.ExtractAll(rootPath, ExtractExistingFileAction.OverwriteSilently);
            return true;
        }
        #endregion
        #region 初始化后端
        /// <summary>
        /// 初始化后端
        /// </summary>
        public static bool InitApiConfig(out string error) {
            error = "";
            var model = GetServerModel("API");
            if (model == null) {
                return false;
            }
            var sitePath = GetSitePath(model.Id, model.SiteName);
            var configPath = Path.Combine(sitePath, "XmlConfig");
            if (!Directory.Exists(configPath)) {
                Directory.CreateDirectory(configPath);
            }
            bool res = WriteDBFile(configPath, out error);
            if (!res) {
                return false;
            }
            res = WriteSystemFile(configPath, out error);
            if (!res) {
                return false;
            }
            res = WriteRedisFile(configPath, out error);
            if (!res) {
                return false;
            }
            res = WriteIocFile(configPath, out error);
            if (!res) {
                return false;
            }
            res = WriteLogCongigFile(configPath, out error);
            if (!res) {
                return false;
            }
            res = WriteHostsFile(configPath, out error);
            if (!res) {
                return false;
            }
            return true;
        }
        /// <summary>
        /// 写入数据库连接文件
        /// </summary>
        /// <param name="error"></param>
        /// <returns></returns>
        private static bool WriteDBFile(string configPath, out string error) {
            error = "";
            var dbModel = DbManager.DbContext.Queryable<DatabaseInfoModel>().First(p => p.Id == "BaseDb");
            if (dbModel == null) {
                error = "未配置主数据库！";
                return false;
            }

            var sourceFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data\\Api\\database.config");

            var dbfile = Path.Combine(configPath, "database.config");
            var allLines = File.ReadAllLines(sourceFile);

            var strDb = CommonServerHelper.GetDBConn(dbModel);
            var strProviderName = "";
            if (dbModel.DBType == 1) {
                strProviderName = "System.Data.SqlClient";
            } else {
                strProviderName = "Oracle.ManagedDataAccess.Client";
            }
            var strList = new List<string>();
            foreach (var line in allLines) {
                var lstr = line.Replace("$C.DbStr", strDb).Replace("$C.DbProvider", strProviderName);
                strList.Add(lstr);
            }
            CommonServerHelper.WriteFile(dbfile, strList);
            return true;
        }

        /// <summary>
        /// 写入数系统字典配置文件
        /// </summary>
        /// <param name="error"></param>
        /// <returns></returns>
        private static bool WriteSystemFile(string configPath, out string error) {
            error = "";
            var commonitemModel = GetServerModel("COMMONITEM");
            var fileStoreModel = GetServerModel("FILESTORE");
            var adapterModel = GetServerModel("ADAPTER");
            var jobModel = GetServerModel("JOBCENTER");
            var apiModel = GetServerModel("API");

            var strList = new List<string>();
            var filePath = Path.Combine(configPath, "system.config");
            strList.Add("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            strList.Add("<appSettings>");
            strList.Add("\t<!-- 附件上传地址 -->");
            strList.Add("\t<add key=\"AnnexesFile\" value=\"\" />");
            strList.Add("\t<!--多语言配置 多语言文件地址-->");
            strList.Add("\t<add key=\"CFG: MULTILANGUAGE:PATH\" value=\"\"   />");
            strList.Add("\t<!--企业号CorpId -->");
            strList.Add("\t<!-- <add key=\"CorpId\" value=\"wxa2c39f6194f4\" /> -->");
            strList.Add("\t<!--企业号凭证密钥 -->");
            strList.Add("\t<!-- <add key=\"CorpSecret\" value=\"eDo9pEOXWqSgWtQ-_1NF_NTmGDTlZ3UFFdF3To-\" /> -->");
            strList.Add("\t<!--设置IP过滤 -->");
            strList.Add("\t<add key=\"FilterIP\" value=\"false\" />");
            strList.Add("\t<!--设置时段过滤 -->");
            strList.Add("\t<add key=\"FilterTime\" value=\"false\" />");
            strList.Add("\t<!--文件缓存地址-->");
            strList.Add("\t<add key=\"TempFilePath\" value=\"C:\\fileTempNew\\\"   />");
            strList.Add("\t<!--配方文件缓存地址-->");
            strList.Add("\t<add key=\"FormulaFilePath\" value=\"\" />");
            strList.Add("\t<!--配方报告单缓存地址-->");
            strList.Add("\t<add key=\"ExpReportFilePath\" value=\"\" />");
            strList.Add("\t<!--host文件地址-->");
            strList.Add("\t<add key=\"HostPath\" value=\"XmlConfig\\Hosts.xml\" />");
            strList.Add("\t<!-- SignalR服务接口-->");
            strList.Add("\t<add key=\"IMUrl\" value=\"\" />");
            strList.Add("\t<!-- 索引文件的存储位置-->");
            strList.Add("\t<!-- <add key=\"IndexPath\" value=\"\" /> -->");
            strList.Add("\t<!-- 是否启用js、css压缩-->");
            strList.Add("\t<!-- <add key=\"JsCompressor\" value=\"false\" /> -->");
            strList.Add("\t<!-- 是否启用js、css缓存-->");
            strList.Add("\t<!-- <add key=\"JsCompressorCache\" value=\"false\" /> -->");
            strList.Add("\t<!--是否记录数据库运行sql到文件 -->");
            strList.Add("\t<add key=\"LOG:DATABASE\" value=\"true\"  />");
            strList.Add("\t<!--是否记录数据库运行sql到文件 -->");
            strList.Add("\t<add key=\"LOG:LEVEL\" value=\"FATAL,ERROR,WARN,INFO,DEBUG\" />");
            strList.Add("\t<!-- 日志记录配置 -->");
            strList.Add("\t<add key=\"LOG:SYSTEM\" value=\"\"    />");
            strList.Add("\t<add key=\"LOG:SYSTEM:CATEGORY\" value=\"\"    />");
            strList.Add("\t<add key=\"LOG:SYSTEM:FUNCTIONMODULE\" value=\"\"    />");
            strList.Add("\t<add key=\"LOG:SYSTEM:OPERATETYPE\" value=\"\"    />");
            strList.Add("\t<add key=\"LOG:SYSTEM:PLATFORM\" value=\"\"    />");
            strList.Add("\t<!-- <add key=\"MailHost\" value=\"\" /> -->");
            strList.Add("\t<!-- <add key=\"MailName\" value=\"\" /> -->");
            strList.Add("\t<!-- <add key=\"MailPassword\" value=\"\" /> -->");
            strList.Add("\t<!-- <add key=\"MailUserName\" value=\"\" /> -->");
            strList.Add("\t<!-- 钉钉配置 -->");
            strList.Add("\t<add key=\"OAUTH:DINGTALK:CLIENTID\" value=\"\" />");
            strList.Add("\t<add key=\"OAUTH:DINGTALK:CLIENTSECRET\" value=\"\" />");
            strList.Add("\t<!-- 微信配置 -->");
            strList.Add("\t<add key=\"OAUTH:WECHAT:APPID\" value=\"\" />");
            strList.Add("\t<add key=\"OAUTH:WECHAT:APPSECRET\" value=\"\" />");
            strList.Add("\t<add key=\"OAUTH:WECHAT:TEMPLATEID\" value=\"\" />");
            strList.Add("\t<add key=\"OAUTH:WECHAT:URLTOKEN\" value=\"\" />");
            strList.Add("\t");
            strList.Add("\t<!-- <add key=\"Pdf2htmlEX\" value=\"\" /> -->");
            strList.Add("\t");
            strList.Add("\t<!-- ######### RPC ########## -->");
            strList.Add("\t<!-- 授权中心服务器服务端口 -->");
            strList.Add("\t<add key=\"RPC:ACTIVATE:URL\" value=\"http://1.116.82.129:30130\"  />");
            strList.Add("\t<!-- 推送ERP的BOM查询路径 -反向查询 -->");
            strList.Add("\t<add key=\"RPC:ADAPTER:BOMCLASS\" value=\"PARTTOPART,-FORMULATOPART, PARTTOFORMULA\"  />");
            strList.Add("\t<!-- 推送ERP的BOM定版验证 -->");
            strList.Add("\t<add key=\"RPC:ADAPTER:BOMVALIDCLASS\" value=\"PART, SYS_FORMULA\"  />");
            strList.Add("\t<!-- Adapter 服务 -->");
            strList.Add($"\t<add key=\"RPC:ADAPTER:URL\" value=\"http://localhost:{adapterModel?.SitePort}\"  />");
            strList.Add("\t<!-- CommonItem 服务-->");
            strList.Add($"\t<add key=\"RPC:COMMONITEM:URL\" value=\"http://localhost:{commonitemModel?.SitePort}\"   />");
            strList.Add("\t<!-- ClientServer C端服务 -->");
            strList.Add("\t<add key=\"RPC:CS:URL\" value=\"http://localhost:3000\" />");
            strList.Add("\t<!-- FileStore 文件服务器 -->");
            strList.Add($"\t<add key=\"RPC:FILESTONE:URL\" value=\"http://localhost:{fileStoreModel?.SitePort}\"   />");
            strList.Add("\t<!-- JobCenter 定时任务 -->");
            strList.Add($"\t<add key=\"RPC:JOB:URL\" value=\"http://localhost:{jobModel?.SitePort}\"   />");
            strList.Add("\t<!-- 光华OA项目暂存发布开关 0 1 -->");
            strList.Add("\t<add key=\"RPC:OA:PROJECTTEMPSTORE\" value=\"0\" />");
            strList.Add("\t<!-- 祥利OA变更流程发布开关 0 1-->");
            strList.Add("\t<add key=\"RPC:OA:WORKFLOW\" value=\"1\" />");
            strList.Add("\t<!--ONLYOFFICE服务地址-->");
            strList.Add("\t<add key=\"RPC ONLYOFFICE:URL\" value=\"http://localhost:3319\"   />");
            strList.Add("\t<!-- PYTHON统计服务地址 -->");
            strList.Add("\t<add key=\"RPC:PYSTAT:URL\" value=\"http://localhost:3131\" />");
            strList.Add("\t<!-- 当前站点地址 -->");
            strList.Add($"\t<add key=\"RPC:WEBSITE:URL\" value=\"http://localhost:{apiModel?.SitePort}\"   />");
            strList.Add("\t<!-- 是否启用新版文件服务器 true false -->");
            strList.Add("\t<add key=\"RPC:WEBSITE:USENEWFILESTORE\" value=\"true\"  />");
            strList.Add("\t<!-- 软件名称 -->");
            strList.Add("\t<!-- <add key=\"SoftName\" value=\"\" /> -->");
            strList.Add("\t<!--head 头像存储地址 -->");
            strList.Add("\t<!-- <add key=\"fileHeadImg\" value=\"\" /> -->");
            strList.Add("\t<!-- <add key=\"fileAppDTImg\" value=\"\" /> -->");
            strList.Add("\t<!-- 空闲时间设定(分钟)-->");
            strList.Add("\t<add key=\"idleTime\" value=\"120\"/>");
            strList.Add("\t<!--Redis 缓存前缀 -->");
            strList.Add("\t<add key=\"RedisPrev\" value=\"LRADMS\" />");
            strList.Add("</appSettings>");
            CommonServerHelper.WriteFile(filePath, strList);
            return true;
        }

        /// <summary>
        /// 写入数Reids配置文件
        /// </summary>
        /// <param name="error"></param>
        /// <returns></returns>
        private static bool WriteRedisFile(string configPath, out string error) {
            error = "";
            var serverModel = GetServerModel("REDIS");
            var soureFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data\\Api\\redis.config");
            var strList = new List<string>();
            var filePath = Path.Combine(configPath, "redis.config");

            var allLines = File.ReadAllLines(soureFile);
            foreach (var line in allLines) {
                var lstr = line.Replace("$C.PORT", serverModel?.SitePort.ToString());
                strList.Add(lstr);
            }
            CommonServerHelper.WriteFile(filePath, strList);
            return true;
        }
        /// <summary>
        /// 写入数ioc配置文件
        /// </summary>
        /// <param name="error"></param>
        /// <returns></returns>
        private static bool WriteIocFile(string configPath, out string error) {
            error = "";
            var sourcePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data\\Api\\ioc.config");
            var filePath = Path.Combine(configPath, "ioc.config");
            try {
                File.Copy(sourcePath, filePath, true);
            } catch (Exception ex) {
                error = ex.Message;
                return false;
            }
            return true;
        }
        /// <summary>
        /// 写入数日志配置文件
        /// </summary>
        /// <param name="error"></param>
        /// <returns></returns>
        private static bool WriteLogCongigFile(string configPath, out string error) {
            error = "";
            var sourcePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data\\log4net.config");
            var filePath = Path.Combine(configPath, "log4net.config");
            try {
                File.Copy(sourcePath, filePath, true);
            } catch (Exception ex) {
                error = ex.Message;
                return false;
            }
            return true;
        }
        /// <summary>
        /// 写入数Hosts配置文件
        /// </summary>
        /// <param name="error"></param>
        /// <returns></returns>
        private static bool WriteHostsFile(string configPath, out string error) {
            error = "";
            var strList = new List<string>();
            var filePath = Path.Combine(configPath, "Hosts.xml");
            strList.Add("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            strList.Add("<Hosts>");
            strList.Add("\t<FileServer>");
            strList.Add("\t\t<oid>ef3bec9b-a926-4322-8634-227ad6a5d0d7</oid>");
            strList.Add("\t\t<hostName>localhost</hostName>");
            strList.Add($"\t\t<ipAddress>{GetLocalIP()}</ipAddress>");
            strList.Add("\t\t<port>8011</port>");
            strList.Add("\t\t<monitorPort>8012</monitorPort>");
            strList.Add("\t\t<bufferPath>c:\\tifs_temp</bufferPath>");
            strList.Add("\t\t<bufferSize>524288</bufferSize>");
            strList.Add("\t\t<maxPoolNum>100</maxPoolNum>");
            strList.Add("\t\t<minPoolNum>10</minPoolNum>");
            strList.Add("\t\t<threadTimeOut>0</threadTimeOut>");
            strList.Add("\t\t<gcPollingTime>300</gcPollingTime>");
            strList.Add("\t\t<allowDebugLog>true</allowDebugLog>");
            strList.Add("\t\t<fileBuffSize>1000</fileBuffSize>");
            strList.Add("\t\t<bufferClearSize>200</bufferClearSize>");
            strList.Add("\t</FileServer>");
            strList.Add("</Hosts>");
            CommonServerHelper.WriteFile(filePath, strList);
            return true;
        }

        #endregion
      

        #region 服务安装
        #region Nginx 服务
        /// <summary>
        /// 
        /// </summary>
        private static void AddNginxFile() {
            var setting = DbManager.DbContext.Queryable<SystemSettingModel>().Where(p => p.Name == "RootDic").First();
            string rootPath = setting?.Value?.ToString() ?? string.Empty;
            if (rootPath.IsEmpty()) {
                return;
            }
            var nginxdic = Path.Combine(rootPath, "Nginx");
            if (!Directory.Exists(nginxdic)) {
                Directory.CreateDirectory(nginxdic);
            }
            var nginxPath = Path.Combine(nginxdic, "nginx.exe");
            if (!File.Exists(nginxPath)) {
                var zipPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data\\nginx.zip");
                using (ZipFile zip = new ZipFile(zipPath)) {
                    zip.ExtractAll(nginxdic, ExtractExistingFileAction.OverwriteSilently);
                }
            }
        }
        /// <summary>
        /// 安装服务
        /// </summary>
        public static bool NginxInstall(ServerModel site, out string error) {
            AddNginxFile();
            error = "";
            var path = GetSitePath(site.Id, site.SiteName);
            if (!Directory.Exists(path)) {
                error = $"未找到{site.SiteLabel}服务文件夹:{path}";
                return false;
            }
            var apiModel = GetServerModel("API");

            //nginx
            var setting = DbManager.DbContext.Queryable<SystemSettingModel>().Where(p => p.Name == "RootDic").First();
            string rootPath = setting?.Value?.ToString() ?? string.Empty;
            if (rootPath.IsEmpty()) {
                return false;
            }
            var httpPath = Path.Combine(rootPath, $"Nginx/conf/vhost/plm-http.conf");
            WriteNginxConf(site.SitePort, path, apiModel, httpPath);
            var httpsPath = Path.Combine(rootPath, $"Nginx/conf/vhost/plm-https.conf");
            WriteNginxConf(site.SitePort, path, apiModel, httpsPath, true);
            return true;
        }
        /// <summary>
        /// 
        /// </summary>
        private static void WriteNginxConf(int port, string sitepath, ServerModel apiSite, string filepath, bool isHttps = false) {
            var tempfilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data\\plm-http.conf");
            var allLine = File.ReadAllLines(tempfilePath);
            var list = new List<string>();
            foreach (var item in allLine) {
                var i = item.Replace("$C.Port", port.ToString()).Replace("$C.OnlyOfficeUrl", $"http://{GetLocalIP()}:3319").Replace("$C.WebPath", $"{sitepath.Replace("\\", "/")}").Replace("$C.ApiUrl", $"http://{GetLocalIP()}:{apiSite?.SitePort}");
                list.Add(i);
            }
            CommonServerHelper.WriteFile(filepath, list);
            return;
        }

        /// <summary>
        /// 卸载服务
        /// </summary>
        public static bool NginxUninstall(ServerModel site, out string error) {
            error = "";
            var path = GetSitePath(site.Id, site.SiteName);
            if (!Directory.Exists(path)) {
                error = $"未找到{site.SiteLabel}服务文件夹:{path}";
                return false;
            }
            //nginx
            var setting = DbManager.DbContext.Queryable<SystemSettingModel>().Where(p => p.Name == "RootDic").First();
            string rootPath = setting?.Value?.ToString() ?? string.Empty;
            if (rootPath.IsEmpty()) {
                return false;
            }
            var nginxConfigPath = Path.Combine(rootPath, $"Nginx/conf/vhost/plm-http.conf");
            if (File.Exists(nginxConfigPath)) {
                File.Delete(nginxConfigPath);
            }
            return true;
        }



        #endregion
        #region Redis 服务
        /// <summary>
        /// 安装Redis 服务
        /// </summary>
        public static bool RedisServiceInstall(ServerModel site, out string error) {
            error = "";
            var path = GetSitePath(site.Id, site.SiteName);
            if (!Directory.Exists(path)) {
                error = $"未找到Redis服务文件夹:{path}";
                return false;
            }
            var exepath = Path.Combine(path, "redis-server.exe");
            if (!File.Exists(exepath)) {
                error = $"路径:{exepath},文件未找到";
                return false;
            }
            var settingFile = Path.Combine(path, "redis.windows-service.conf");
            if (!File.Exists(settingFile)) {
                error = $"路径:{settingFile},文件未找到";
                return false;
            }
            ServiceManage.ServiceInstall(exepath, site.SiteName, true, $"--service-install {settingFile} --loglevel verbose --service-name {site.SiteName.ToLower()}  --port {site.SitePort}");
            return true;
        }
        /// <summary>
        /// 卸载Redis 服务
        /// </summary>
        public static bool RedisServiceUninstall(ServerModel site, out string error) {
            error = "";
            var path = GetSitePath(site.Id, site.SiteName);
            if (!Directory.Exists(path)) {
                error = $"未找到Redis服务文件夹:{path}";
                return false;
            }
            var exepath = Path.Combine(path, "redis-server.exe");
            if (!File.Exists(exepath)) {
                error = $"路径:{exepath},文件未找到";
                return false;
            }
            ServiceManage.ServiceUninstall(exepath, site.SiteName, true, $" --service-uninstall --service-name {site.SiteName}");
            return true;
        }
        #endregion
        #region 前端服务


        #endregion

        #region 后端服务


        #endregion
        #region IIS 
        /// <summary>
        /// 安装IIS
        /// </summary>
        public static bool IISServiceInstall(ServerModel site, out string error) {
            error = "";
            var path = GetSitePath(site.Id, site.SiteName);
            var filePath = Path.Combine(path, $"Global.asax");
            if (!File.Exists(filePath)) {
                error = $"程序文件不完整，请在【{path}】放入完整的程序包！";
                return false;
            }
            CreateIISSite(site.SiteName, site.SitePort, path);
            return true;
        }
        /// <summary>
        /// 卸载IIS
        /// </summary>
        public static bool IISServiceUninstall(ServerModel site, out string error) {
            error = "";
            var path = GetSitePath(site.Id, site.SiteName);
            if (!Directory.Exists(path)) {
                error = $"未找到服务文件夹:{path}";
                return false;
            }
            RemoveIISSite(site.SiteName);
            return true;
        }

        /// <summary>
        /// 创建IIS
        /// </summary>
        /// <param name="webName"></param>
        /// <param name="port"></param>
        /// <param name="path"></param>
        private static void CreateIISSite(string webName, int port, string path) {
            using ServerManager sm = new ServerManager();
            //创建应用程序池
            ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == webName)!;
            if (appPool == null) {
                appPool = sm.ApplicationPools.Add(webName);
                appPool.AutoStart = false;
                appPool.Enable32BitAppOnWin64 = true;
                appPool.QueueLength = 10000;
                appPool.StartMode = StartMode.AlwaysRunning;//启动模式
                appPool.Recycling.PeriodicRestart.Time = new TimeSpan();//回收时间间隔
                appPool.ProcessModel.IdleTimeout = new TimeSpan();//闲置超时
                appPool.ProcessModel.MaxProcesses = 1;//最大工作进程数
            }
            //创建Site
            Site site = sm.Sites.FirstOrDefault(x => x.Name == webName)!;
            if (site == null) {
                site = sm.Sites.Add(webName, path, port);
                site.ServerAutoStart = false;

                site.Bindings[0].EndPoint.Port = port;
                Application root = site.Applications["/"];
                root.ApplicationPoolName = webName;
                root.VirtualDirectories["/"].PhysicalPath = path;
                root.SetAttributeValue("preloadEnabled", true); /*预加载*/
            }
            sm.CommitChanges();
        }
        /// <summary>
        /// 删除IIS 站点
        /// </summary>
        /// <param name="serverIP">服务器地址</param>
        /// <param name="webName">站点名</param>
        private static void RemoveIISSite(string webName) {
            string path = string.Empty;
            using ServerManager sm = new ServerManager();
            //删除应用程序池
            ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == webName)!;
            if (appPool != null) {
                //appPool.Stop();
                sm.ApplicationPools.Remove(appPool);
            }
            //删除Site
            Site site = sm.Sites.FirstOrDefault(x => x.Name == webName)!;
            if (site != null) {
                path = site.Applications["/"].VirtualDirectories["/"].PhysicalPath;
                sm.Sites.Remove(site);
            }
            sm.CommitChanges();
        }
        #endregion
        #region 公共服务
        /// <summary>
        /// 安装服务
        /// </summary>
        public static bool CommonServiceInstall(ServerModel site, string fileName, out string error) {
            error = "";
            var path = GetSitePath(site.Id, site.SiteName);
            if (!Directory.Exists(path)) {
                error = $"未找到{site.SiteLabel}服务文件夹:{path}";
                return false;
            }
            var exepath = Path.Combine(path, $"{fileName}.exe");
            if (!File.Exists(exepath)) {
                error = $"路径:{exepath},文件未找到";
                return false;
            }
            ServiceManage.ServiceInstall(exepath, site.SiteName);
            return true;
        }
        /// <summary>
        /// 卸载服务
        /// </summary>
        public static bool CommonServiceUninstall(ServerModel site, out string error) {
            error = "";
            var path = GetSitePath(site.Id, site.SiteName);
            if (!Directory.Exists(path)) {
                error = $"未找到{site.SiteLabel}服务文件夹:{path}";
                return false;
            }
            ServiceManage.ServiceUninstall(site.SiteName);
            return true;
        }
        #endregion
        #endregion

        #region 服务启动
        /// <summary>
        /// Nginx启动服务
        /// </summary>
        public static bool NginxSatrt(ServerModel site, out string error) {
            bool state = false;
            error = "";
            var setting = DbManager.DbContext.Queryable<SystemSettingModel>().Where(p => p.Name == "RootDic").First();
            string rootPath = setting?.Value?.ToString() ?? string.Empty;
            if (rootPath.IsEmpty()) {
                return false;
            }
            var path = GetSitePath(site.Id, site.SiteName);
            if (!Directory.Exists(path)) {
                error = $"未找到{site.SiteLabel}服务文件夹:{path}";
                return state;
            }
            var nginxPath = Path.Combine(rootPath, $"Nginx");
            if (!Directory.Exists(nginxPath)) {
                error = $"路径:{nginxPath},文件未找到";
                return state;
            }
            var cmdStr = $" cd /d {nginxPath}";
            CmdHelper.CmdCall(false, cmdStr, "&&", "start nginx");
            Thread.Sleep(1500);
            state = CheckNginxState(rootPath);
            return state;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rootPath"></param>
        /// <returns></returns>
        private static bool CheckNginxState(string rootPath) {
            int index = 0;
            bool state = false;
            while (!state && index < 5) {
                index++;
                var nginxPidPath = Path.Combine(rootPath, "Nginx/logs/nginx.pid");
                if (File.Exists(nginxPidPath)) {
                    var id = File.ReadAllText(nginxPidPath, Encoding.Default);
                    if (!id.IsEmpty()) {
                        Process[] pslist = Process.GetProcessesByName("nginx");
                        Process ps = pslist.FirstOrDefault(x => x.Id == id.ToIntOrNull())!;
                        state = ps != null;
                        if (ps != null) {
                            state = true;
                            break;
                        } else {
                            Thread.Sleep(500);
                        }
                    } else {
                        state = false;
                        Thread.Sleep(500);
                    }
                }
            }
            return state;
        }
        /// <summary>
        /// 通用服务启动
        /// </summary>
        public static bool ServiceStart(string serviceName, out string error) {
            error = "";
            bool state = false;
            try {
                state = ServiceManage.ServiceStart(serviceName);
            } catch (Exception ex) {
                error = ex.Message;
            }
            return state;
        }
        /// <summary>
        /// 启动IIS网站
        /// </summary>
        public static bool StartSite(string webSiteName, out string error) {
            if (!StartApplicationPool(webSiteName)) {
                error = $"应用池【{webSiteName}】启动失败";
                return false;
            }
            bool state = false;
            error = "";
            int index = 0;
            try {
                using ServerManager sm = new();
                while (!state && index <= 5) {
                    index++;
                    Site site = sm.Sites.FirstOrDefault(x => x.Name == webSiteName)!;
                    if (site != null && site.State == ObjectState.Stopped) {
                        if (site.Start() == ObjectState.Started) {
                            state = true;
                        } else {
                            Thread.Sleep(500);
                        }
                    }
                }
            } catch (Exception ex) {
                error = ex.Message;
            }
            return state;
        }
        /// <summary>
        /// 启动IIS应用池
        /// </summary>
        public static bool StartApplicationPool(string appPoolName) {
            using ServerManager sm = new();
            //应用程序池
            ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == appPoolName)!;
            if (appPool == null) {
                return false;
            }
            if (appPool.State == ObjectState.Started) {
                return true;
            }
            if (appPool.State == ObjectState.Stopped) {
                appPool.Start();
                sm.CommitChanges();
            }
            int index = 0;
            bool state = false;
            while (index <= 5 && !state) {
                if (appPool.State == ObjectState.Starting) {
                    Thread.Sleep(1000);
                } else {
                    state = appPool.State == ObjectState.Started;
                    index++;
                }
            }
            return state;
        }
        #endregion
        #region 服务停止
        /// <summary>
        /// Nginx停止服务
        /// </summary>
        public static bool NginxStop(ServerModel site, out string error) {
            bool state = false;
            error = "";
            var setting = DbManager.DbContext.Queryable<SystemSettingModel>().Where(p => p.Name == "RootDic").First();
            string rootPath = setting?.Value?.ToString() ?? string.Empty;
            if (rootPath.IsEmpty()) {
                return false;
            }
            var path = GetSitePath(site.Id, site.SiteName);
            if (!Directory.Exists(path)) {
                error = $"未找到{site.SiteLabel}服务文件夹:{path}";
                return state;
            }
            var nginxPath = Path.Combine(rootPath, $"Nginx");
            if (!Directory.Exists(nginxPath)) {
                error = $"路径:{nginxPath},文件未找到";
                return state;
            }
            var cmdStr = $" cd /d {nginxPath}";
            var res = CmdHelper.CmdCall(true, cmdStr, "&&", "nginx -s quit");
            var nginxPidPath = Path.Combine(rootPath, "Nginx/logs/nginx.pid");
            Thread.Sleep(1000);
            state = !File.Exists(nginxPidPath);
            return state;
        }
        /// <summary>
        /// 通用服务停止
        /// </summary>
        public static bool ServiceStop(string serviceName, out string error) {
            error = "";
            bool state = false;
            try {
                state = ServiceManage.ServiceStop(serviceName);
            } catch (Exception ex) {
                error = ex.Message;
            }
            return state;
        }
        /// <summary>
        /// 关闭IIS网站
        /// </summary>
        /// <param name="webSiteName"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static bool StopSite(ServerModel model, LogHandler logHandler) {
            if (!StopApplicationPool(model.SiteName)) {
                logHandler.WriteLog("错误", $"应用池【{model.SiteName}】停止失败");
                return false;
            }
            try {
                using ServerManager sm = new ServerManager();
                Site site = sm.Sites.FirstOrDefault(x => x.Name == model.SiteName)!;
                if (site == null) {
                    logHandler.WriteLog("错误", $"【{model.SiteName}】网站不存在");
                    return false;
                }
                if (site.State == ObjectState.Stopped) {
                    return true;
                }
                if (site.State == ObjectState.Started) {
                    site.Stop();
                    sm.CommitChanges();
                }
                bool state = false;
                int index = 0;
                while (!state && index <= 5) {
                    index++;
                    if (site.State == ObjectState.Stopped) {
                        state = true;
                    } else {
                        Thread.Sleep(500);
                    }
                }
                return state;
            } catch (Exception ex) {
                logHandler.WriteLog("错误", ex.Message);
                return false;
            }
        }
        /// <summary>
        /// 关闭IIS应用池
        /// </summary>
        private static bool StopApplicationPool(string appPoolName) {
            using ServerManager sm = new();
            //应用程序池
            ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == appPoolName)!;
            if (appPool == null) {
                return false;
            }
            if (appPool.State == ObjectState.Stopped) {
                return true;
            }
            if (appPool.State == ObjectState.Started) {
                appPool.Stop();
            }
            int index = 0;
            bool state = false;
            while (index <= 5 && !state) {
                if (appPool.State == ObjectState.Stopping) {
                    Thread.Sleep(1000);
                } else {
                    state = appPool.State == ObjectState.Stopped;
                    index++;
                }
            }
            return state;
        }
        #endregion
        #region 服务更新
        /// <summary>
        /// 
        /// </summary>
        public static bool UpdateSite(ServerModel CardModel, string zipPath, out string error) {
            error = "";
            var extractPath = GetSitePath(CardModel.Id, CardModel.SiteName);
            try {
                using ZipFile zip = new(zipPath);
                zip.ExtractAll(extractPath, ExtractExistingFileAction.OverwriteSilently);
                return true;
            } catch (Exception ex) {
                error = ex.Message;
            }
            return false;
        }
        /// <summary>
        /// 备份网站
        /// </summary>
        public static bool BackupSite(ServerModel CardModel, out string error) {
            error = "";
            var setting = DbManager.DbContext.Queryable<SystemSettingModel>().Where(p => p.Name == "RootDic").First();
            string rootPath = setting?.Value?.ToString() ?? string.Empty;
            var backupPath = Path.Combine(rootPath, "BACKUP");
            if (!Directory.Exists(backupPath)) {
                Directory.CreateDirectory(backupPath);
            }
            var zipPath = Path.Combine(backupPath, $"{CardModel.SiteName}_{DateTime.Now:yyyyMMdd}.zip");
            var sitePath = GetSitePath(CardModel.Id, CardModel.SiteName);
            var fileList = Directory.GetFiles(sitePath);
            if (!fileList.Any()) {
                return true;
            }
            try {
                using ZipFile zip = new(Encoding.Default);
                zip.AddDirectory(sitePath);
                zip.Save(zipPath);
                return true;
            } catch (Exception ex) {
                error = ex.Message;
            }
            return false;
        }
        #endregion

        #region 服务自启动
        /// <summary>
        /// 检测服务启动
        /// </summary>
        public static ServerModel RedisAutoStart(ServerModel model, LogHandler logHandler) {
            var sc = ServiceManage.GetService(model.SiteName.ToLower());
            if (sc == null) {
                logHandler.WriteLog("错误", $"【{model.SiteName.ToLower()}】服务不存在");
                model.Status = 1;
                ServerService.UpdateServerModel(model);
                return model;
            }
            if (sc.Status == ServiceControllerStatus.Stopped) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止，正在自动重启");
                var state = ServiceStart(model.SiteName.ToLower(), out string error);
                if (!state) {
                    logHandler.WriteLog("错误", $"【{model.SiteLabel}】服务无法启动！ {error}");
                    model.Status = 3;
                    ServerService.UpdateServerModel(model);
                    return model;
                } else {
                    model.Status = 4;
                    ServerService.UpdateServerModel(model);
                    return model;
                }
            }
            if (sc.Status == ServiceControllerStatus.Running) {
                model.Status = 4;
                ServerService.UpdateServerModel(model);
            }
            return model;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rootPath"></param>
        /// <returns></returns>
        public static ServerModel NginxAutoStart(ServerModel model, LogHandler logHandler) {
            bool state = false;
            string error = "";
            var setting = DbManager.DbContext.Queryable<SystemSettingModel>().Where(p => p.Name == "RootDic").First();
            string rootPath = setting?.Value?.ToString() ?? string.Empty;
            var nginxPidPath = Path.Combine(rootPath, "Nginx/logs/nginx.pid");
            if (!File.Exists(nginxPidPath)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止，正在自动重启");
                state = NginxSatrt(model, out error);
                if (state) {
                    model.Status = 4;
                    ServerService.UpdateServerModel(model);
                } else {
                    model.Status = 3;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            } else {
                var id = File.ReadAllText(nginxPidPath, Encoding.Default);
                if (!id.IsEmpty()) {
                    Process ps = Process.GetProcessById(id.ToIntOrNull());
                    if (ps == null) {
                        logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止，正在自动重启");
                        state = NginxSatrt(model, out error);
                        if (state) {
                            model.Status = 4;
                            ServerService.UpdateServerModel(model);
                        } else {
                            model.Status = 3;
                            ServerService.UpdateServerModel(model);
                        }
                        return model;
                    } else {
                        model.Status = 4;
                        ServerService.UpdateServerModel(model);
                        return model;
                    }
                } else {
                    logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止，正在自动重启");
                    state = NginxSatrt(model, out error);
                    if (state) {
                        model.Status = 4;
                        ServerService.UpdateServerModel(model);
                    } else {
                        model.Status = 3;
                        ServerService.UpdateServerModel(model);
                    }
                    return model;
                }
            }
        }
        /// <summary>
        /// 检测IIS网站
        /// </summary>
        /// <param name="model"></param>
        public static ServerModel IISAutoStart(ServerModel model, LogHandler logHandler) {
            bool res = ApplicationPoolAutoStart(model.SiteName);
            if (!res) {
                logHandler.WriteLog("错误", $"【{model.SiteLabel}】应用池无法启动");
                model.Status = 1;
                ServerService.UpdateServerModel(model);
                return model;
            }
            using ServerManager sm = new ServerManager();
            Site site = sm.Sites.FirstOrDefault(x => x.Name == model.SiteName)!;
            if (site == null) {
                logHandler.WriteLog("错误", $"【{model.SiteName}】网站不存在");
                model.Status = 1;
                ServerService.UpdateServerModel(model);
                return model;
            }
            if (site.State == ObjectState.Stopped) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止，正在自动重启");
                res = StartSite(model.SiteName, out string error);
                if (!res) {
                    logHandler.WriteLog("错误", $"【{model.SiteLabel}】服务无法启动！ {error}");
                    model.Status = 3;
                    ServerService.UpdateServerModel(model);
                    return model;
                } else {
                    model.Status = 4;
                    ServerService.UpdateServerModel(model);
                    return model;
                }
            }
            if (site.State == ObjectState.Started) {
                model.Status = 4;
                ServerService.UpdateServerModel(model);
            }
            return model;

        }
        /// <summary>
        /// 检测IIS网站
        /// </summary>
        /// <param name="model"></param>
        public static bool ApplicationPoolAutoStart(string appPoolName) {
            //应用程序池
            using ServerManager sm = new ServerManager();
            ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == appPoolName)!;
            if (appPool == null) {
                return false;
            }
            if (appPool.State == ObjectState.Started) {
                return true;
            }
            bool res = StartApplicationPool(appPoolName);
            return res;
        }

        /// <summary>
        /// 检测服务启动
        /// </summary>
        public static ServerModel ServiceAutoStart(ServerModel model, LogHandler logHandler) {
            var sc = ServiceManage.GetService(model.SiteName);
            if (sc == null) {
                logHandler.WriteLog("错误", $"【{model.SiteName}】服务不存在");
                model.Status = 1;
                ServerService.UpdateServerModel(model);
                return model;
            }
            if (sc.Status == ServiceControllerStatus.Stopped) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止，正在自动重启");
                var state = ServiceStart(model.SiteName, out string error);
                if (!state) {
                    logHandler.WriteLog("错误", $"【{model.SiteLabel}】服务无法启动！ {error}");
                    model.Status = 3;
                    ServerService.UpdateServerModel(model);
                    return model;
                } else {
                    model.Status = 4;
                    ServerService.UpdateServerModel(model);
                    return model;
                }
            }
            if (sc.Status == ServiceControllerStatus.Running) {
                model.Status = 4;
                ServerService.UpdateServerModel(model);
            }
            return model;
        }
        #endregion
        #region 服务检测
        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <param name="logHandler"></param>
        public static ServerModel RedisCheck(ServerModel model, LogHandler logHandler) {
            var path = GetSitePath(model.Id, model.SiteName);
            if (!Directory.Exists(path)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未配置，请先配置服务信息");
                if (model.Status != 0) {
                    model.Status = 0;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var filePath = Path.Combine(path, $"redis-server.exe");
            if (!File.Exists(filePath)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未初始化配置，请先初始化配置");
                if (model.Status != 1) {
                    model.Status = 1;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            using ServiceController control = new(model.SiteName.ToLower());
            if (control == null) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未部署，请先安装部署");
                if (model.Status != 2) {
                    model.Status = 2;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            if (control.Status == ServiceControllerStatus.Stopped) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止");
                if (model.Status != 3) {
                    model.Status = 3;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            if (control.Status == ServiceControllerStatus.Running) {
                if (model.Status != 4) {
                    model.Status = 4;
                    ServerService.UpdateServerModel(model);
                }
            }
            return model;
        }
        /// <summary>
        /// 
        /// </summary>
        public static ServerModel NginxCheck(ServerModel model, LogHandler logHandler) {
            var path = GetSitePath(model.Id, model.SiteName);
            if (!Directory.Exists(path)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未配置，请先配置服务信息");
                if (model.Status != 0) {
                    model.Status = 0;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var configPath = Path.Combine(path, $"config.js");
            if (!File.Exists(configPath)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未初始化配置，请先初始化配置");
                if (model.Status != 1) {
                    model.Status = 1;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var filePath = Path.Combine(path, $"index.html");
            if (!File.Exists(filePath)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】文件不完整，请先放入完整的程序包！");
                if (model.Status != 2) {
                    model.Status = 2;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var setting = DbManager.DbContext.Queryable<SystemSettingModel>().Where(p => p.Name == "RootDic").First();
            string rootPath = setting?.Value?.ToString() ?? string.Empty;
            var nginxPidPath = Path.Combine(rootPath, "Nginx/logs/nginx.pid");
            if (!File.Exists(nginxPidPath)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止");
                if (model.Status != 3) {
                    model.Status = 3;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var id = File.ReadAllText(nginxPidPath, Encoding.Default);
            if (!id.IsEmpty()) {
                Process ps = Process.GetProcessById(id.ToIntOrNull());
                if (ps == null) {
                    logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止");
                    if (model.Status != 3) {
                        model.Status = 3;
                        ServerService.UpdateServerModel(model);
                    }
                } else {
                    if (model.Status != 4) {
                        model.Status = 4;
                        ServerService.UpdateServerModel(model);
                    }
                }
            } else {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止");
                if (model.Status != 3) {
                    model.Status = 3;
                    ServerService.UpdateServerModel(model);
                }
            }
            return model;
        }
        /// <summary>
        /// 
        /// </summary>
        public static ServerModel IISCheck(ServerModel model, LogHandler logHandler) {
            var path = GetSitePath(model.Id, model.SiteName);
            if (!Directory.Exists(path)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未配置，请先配置服务信息");
                if (model.Status != 0) {
                    model.Status = 0;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var configPath = Path.Combine(path, $"XmlConfig\\database.config");
            if (!File.Exists(configPath)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未初始化配置，请先初始化配置");
                if (model.Status != 1) {
                    model.Status = 1;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var filePath = Path.Combine(path, $"Global.asax");
            if (!File.Exists(filePath)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】文件不完整，请先放入完整的程序包！");
                if (model.Status != 2) {
                    model.Status = 2;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            using ServerManager sm = new ServerManager();
            Site site = sm.Sites.FirstOrDefault(x => x.Name == model.SiteName)!;
            ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == model.SiteName)!;
            if (appPool == null || site == null) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未部署，请先安装部署");
                if (model.Status != 2) {
                    model.Status = 2;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            if (appPool.State == ObjectState.Stopped) {
                ApplicationPoolAutoStart(model.SiteName);
            }
            if (site.State == ObjectState.Stopped) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止");
                if (model.Status != 3) {
                    model.Status = 3;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            if (site.State == ObjectState.Started && appPool.State == ObjectState.Started) {
                if (model.Status != 4) {
                    model.Status = 4;
                    ServerService.UpdateServerModel(model);
                }
            }
            return model;
        }
        /// <summary>
        /// 
        /// </summary>
        public static ServerModel ServiceCheck(string serverExeName, ServerModel model, LogHandler logHandler) {
            var path = GetSitePath(model.Id, model.SiteName);
            if (!Directory.Exists(path)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未配置，请先配置服务信息");
                if (model.Status != 0) {
                    model.Status = 0;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var configPath = Path.Combine(path, $"appsettings.json");
            if (!File.Exists(configPath)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未初始化配置，请先初始化配置");
                if (model.Status != 1) {
                    model.Status = 1;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var filePath = Path.Combine(path, $"{serverExeName}.exe");
            if (!File.Exists(filePath)) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】文件不完整，请先放入完整的程序包！");
                if (model.Status != 2) {
                    model.Status = 2;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            var sc = ServiceManage.GetService(model.SiteName);
            if (sc == null) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】未部署，请先安装部署！");
                if (model.Status != 2) {
                    model.Status = 2;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            if (sc.Status == ServiceControllerStatus.Stopped) {
                logHandler.WriteLog("警告", $"检测到【{model.SiteLabel}】服务已停止");
                if (model.Status != 3) {
                    model.Status = 3;
                    ServerService.UpdateServerModel(model);
                }
                return model;
            }
            if (sc.Status == ServiceControllerStatus.Running) {
                if (model.Status != 4) {
                    model.Status = 4;
                    ServerService.UpdateServerModel(model);
                }
            }
            return model;
        }
        #endregion
    }
}
